package com.changjiang.luban.config.interceptor;


import com.changjiang.luban.config.annotation.AuthorizationToken;
import com.changjiang.luban.dao.domain.sys.SysLog;
import com.changjiang.luban.dao.domain.sys.SysUser;
import com.changjiang.luban.service.sys.LogServiceI;
import com.changjiang.luban.service.sys.SysUserServiceI;
import com.changjiang.luban.utils.DateUtils;
import com.changjiang.luban.utils.StringUtils;
import com.changjiang.luban.utils.SystemConstants;
import com.changjiang.luban.utils.data.Tree;
import com.changjiang.luban.utils.http.CookieUtils;
import com.changjiang.luban.utils.http.TokenUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.*;


/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @author changjiang
 * Date: 2018-03-28
 * Time: 16:07
 */
@SuppressWarnings("ALL")
public class TokenInterceptor implements HandlerInterceptor {

    private final static String ACCESS_TOKEN = "accessToken";

    private final static String POST_METHOD = "POST";

    private final static String GET_METHOD = "GET";

    /** 需要添加到日志进行记录的接口后缀名 */
    private final static String LOG_SUFFIX = ".log";

    @Autowired
    private SysUserServiceI userServiceI;

    @Autowired
    private LogServiceI logServiceI;

    /**
     * 在请求处理之前进行调用（Controller方法调用之前）
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        // 判断是否存在令牌信息，如果存在，则允许登录
        Cookie cookie =  CookieUtils.getCookieByName(request,ACCESS_TOKEN);
        if(cookie!=null){
            String accessToken = cookie.getValue();
            if(accessToken!=null){
                Claims claims = TokenUtils.parseJWT(accessToken);
                String loginName = claims.getId();
                SysUser user = userServiceI.findByLoginName(loginName);
                if (user == null) {
                    throw new RuntimeException("用户不存在，请重新登录");
                }
                // 当前登录用户@CurrentUser
                request.setAttribute(SystemConstants.CURRENT_USER_CODE, user.getId());
                List<Tree> treeList = userServiceI.tree(user.getId());
                request.getSession().setAttribute("treeViews",treeList);
                if(POST_METHOD.equals(request.getMethod().toUpperCase())) {
                    log(request, user.getName());
                }
                return true;
            }
        }
        // 判断接口是否需要登录
        AuthorizationToken methodAnnotation = method.getAnnotation(AuthorizationToken.class);
        // 有 @LoginRequired 注解，需要认证
        if (methodAnnotation != null) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
        response.sendRedirect("/login");
        return false;
    }

    public void log(HttpServletRequest request,String userName ){
        if(POST_METHOD.equals(request.getMethod().toUpperCase())){
            String url = request.getRequestURI();
            List<String> urlList = StringUtils.strSplitList(url,"/");
            System.out.println(urlList.get(urlList.size()-1)+"---------"+urlList.get(urlList.size()-1).indexOf("save"));
            if(urlList.get(urlList.size()-1).indexOf("update")>=0||urlList.get(urlList.size()-1).indexOf("save")>=0||urlList.get(urlList.size()-1).indexOf("add")>=0
                    ||urlList.get(urlList.size()-1).indexOf("new")>=0||urlList.get(urlList.size()-1).indexOf("delete")>=0){
                List<Map<String,Object>> api = getController();
                System.out.println(api);
                for (Map<String,Object> map:api) {
                    if(map.get("url").equals(url)){
                        SysLog sysLog = new SysLog();
                        sysLog.setType(1);
                        sysLog.setTitle((String) map.get("name"));
                        sysLog.setOperator(userName);
                        sysLog.setCreateTime(DateUtils.getCurrentSystemDate(DateUtils.DATE_FORMAT_COMPLETE));
                        logServiceI.saveLog(sysLog);
                    }
                }
            }
        }
    }

    @Autowired
    WebApplicationContext applicationContext;

    public List<Map<String,Object>> getController(){
        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
        //获取url与类和方法的对应信息
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
        List<Map<String,Object>> urlList = new ArrayList<>();
        for (RequestMappingInfo info : map.keySet()) {
            //获取url的Set集合，一个方法可能对应多个url
            Set<String> patterns = info.getPatternsCondition().getPatterns();
            Map<String,Object> newMap = new HashMap<>();
            for (String url : patterns) {
                newMap.put("url",url);
                newMap.put("name",info.getName());
            }
            urlList.add(newMap);
        }
        return urlList;
    }
}
